#include <stdlib.h>
#include <string.h>
#include <malloc.h>

#include <time.h>
#include "GL/glut.h"


void *font = GLUT_BITMAP_TIMES_ROMAN_24;

void renderBitmapString(float x, float y, float z, void *font, char *string) 
{ //** func added in 0.1.2
 
	char *c;
	glRasterPos3f(x, y,z);
	for (c=string; *c != '\0'; c++) 
	{
		glutBitmapCharacter(font, *c);
	}
}

const int N = 30;
const int M = 20;
const int scale = 25;

const int w = scale * N;
const int h = scale * M;

static int dir;
static int num = 4;

struct
{	
	int x;
	int y;
} s[100];

struct
{
int Fx;
int Fy;
} m[10];

void drawFruit()
{
	glColor3f(0.0, 0.8, 0.0);
	glRectf(m->Fx*scale, m->Fy*scale, (m->Fx+1)*scale, (m->Fy+1)*scale);
}
void newFruit()
{
	m->Fx = rand() % N;
	m->Fy = rand() % M;
}

void drawField()
{
	glColor3f(0.5, 0.1, 0.1);
	glBegin(GL_LINES);

	for (int i = 0; i < w; i += scale)
	{
		glVertex2f(i, 0);
		glVertex2f(i, h);
	}
	for (int j = 0; j < h; j += scale)
	{
		glVertex2f(0, j);
		glVertex2f(w, j);
	}
	glEnd();
}

void tick()
{
	for (int i = num; i > 0; --i)
	{
		s[i].x = s[i-1].x;
		s[i].y = s[i-1].y;
	}

	if (dir == 0) s[0].y++;
	if (dir == 1) s[0].x--;
	if (dir == 2) s[0].x++;
	if (dir == 3) s[0].y--;

	for (int i = 0; i < 10; i++)
	{
		if ((s[0].x == m[i].Fx) && (s[0].y == m[i].Fy))
				{
				num++;
				newFruit();
				}
	}
	
	//***** control fixed in 0.1.1
	if (s[0].x > N-1) dir = 1;
	if (s[0].x < 0) dir   = 2;
	if (s[0].y > M-1) dir = 3;
	if (s[0].y < 0) dir   = 0;
	//------

	for (int i = 1; i < num; i++)
	{
		if (s[0].x == s[i].x && s[0].y == s[i].y) num = i;
	}
}

void drawSnake()
{
	glColor3f(0.8, 0.2, 0.2);

	for (int i = 0; i < num; i++)
	{
		glRectf(s[i].x * scale, s[i].y * scale, (s[i].x + 1)*scale-2, (s[i].y + 1)*scale-2);
		glColor3f(0.6, 0.4, 0.0);
	}
}

void display()
{	
	glClear(GL_COLOR_BUFFER_BIT);
	for (int i = 0; i < 10; i++) drawFruit();
	drawField();
	drawSnake();

	// *** Scoreboard added in 0.1.2
	glColor3f(1, 1, 1);
	renderBitmapString(720, 460, 0.0, (void *)font,"Your score: ");

	char *a;
	a = (char*)malloc(32 * sizeof(int));

	sprintf(a, "%i", num);
	renderBitmapString(780, 440, 0.0, (void *)font, a);
	//---
	free(a);
	glFlush();
}

void timer(int x)
{
	display();

	tick();
	
	glutTimerFunc(100-(num*2), timer, 0);
}

void keyboard(int key, int a, int b)
{
	switch (key) 
	{
		case 100:
			dir = 1;
			break;
		case 101:
			dir = 0;
			break;
		case 102:
			dir = 2;
			break;
		case 103:
			dir = 3;
			break;
	}
}

int main(int argc, char **argv)
{
	for (int i = 0; i < 10; i++) newFruit();

	s[0].x = 10;
	s[0].y = 10;

	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowSize(w, h);
	glutCreateWindow("Snake on C");
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluOrtho2D(0, w+100, 0, h);

	glutDisplayFunc(display);
	glutTimerFunc(50, timer, 0);	

	glutSpecialFunc(keyboard);
	glutMainLoop();
}

